package com.cloudpivot.receivales.ding.robot.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.dingtalkrobot_1_0.Client;
import com.aliyun.dingtalkrobot_1_0.models.*;
import com.aliyun.tea.TeaException;
import com.aliyun.teautil.models.RuntimeOptions;
import com.cloudpivot.receivales.ding.basic.service.DingBasicService;
import com.cloudpivot.receivales.ding.basic.service.impl.HttpAPIServiceForDing;
import com.cloudpivot.receivales.ding.robot.domain.RobotResDTO;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiRobotSendRequest;
import com.dingtalk.api.response.OapiRobotSendResponse;
import com.taobao.api.ApiException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.List;
import java.util.Map;


/**
 * 机器人服务层
 */

@Slf4j
@Service
public class RobotServiceImpl {

    @Autowired
    private DingBasicService dingBasicService;

    @Autowired
    private HttpAPIServiceForDing httpAPIServiceForDing;

    @Autowired
    private DocSpaceServiceImpl docSpaceService;

    @Value("${dingcallback.orgrobot}")
    private String ROBOTID;

    @Value("${myprops.cpurl}")
    private String CPURL;
    private String MAYCURURL="http://172.17.100.14:8189";

    public JSONObject modeCreate(List<String> lists) {
        if (lists.isEmpty()) {
            return null;
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("title", "提问");
        jsonObject.put("text", "我可以回答");
        int i = 1;
        for (String s : lists) {
            jsonObject.put("actionTitle" + i, s);
//            jsonObject.put("actionURL" + i, "dtmd://dingtalkclient/sendMessage?content=" + encodeS(s));
            jsonObject.put("actionURL" + i, "dtmd://dingtalkclient/sendMessage?content=" + encodeS(s));
            i++;
        }
        return jsonObject;
    }

    /**
     * 知识库的调用信息
     *
     * @param uids
     * @param reqMsg
     */
    public void workspaceCardPush(List<String> uids, String reqMsg,RobotResDTO dto) {
        Map<String, String> map = docSpaceService.searchFileName(reqMsg);
        //整理map为标准 Json 卡片信息
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("title", "知识库查询结果回复");
        StringBuilder sb = new StringBuilder();
        if (map.size() > 0) {
            sb.append("帮您找到如下匹配信息:  \n  ***  \n  ");
            int i = 1;
            for (Map.Entry<String, String> entry : map.entrySet()) {
                sb.append(">* [" + entry.getKey() + "](" + entry.getValue() + ")  \n  ");
                i++;
                if (i > 16) {
                    sb.append("><font color=\"#e91e63\">注意!!!搜索结果多余15个,可以调整关键字再次搜索</font>  \n  ");
                    break;
                }
            }
        } else {
            sb.append("帮您找到如下匹配信息:  \n  ***  \n  >知识库中没有相匹配的文档!!请调整\"关键字\"后搜索  \n  ");
        }
        jsonObject.put("text", sb.toString());
        //卡片推送
        try {
            if (dto.getConversationType().equals("1")) {
                //单聊
                Client client = dingBasicService.createClient();
                String token = dingBasicService.getToken("dingrobottag");
                BatchSendOTOHeaders headers = new BatchSendOTOHeaders();
                headers.xAcsDingtalkAccessToken = token;
                BatchSendOTORequest request = new BatchSendOTORequest().setRobotCode(ROBOTID).setUserIds(uids).setMsgKey("sampleMarkdown").setMsgParam(JSONObject.toJSONString(jsonObject));
                BatchSendOTOResponse response = client.batchSendOTOWithOptions(request, headers, new RuntimeOptions());
                log.info("回答文本服务---->成功");
            }else{
                //群聊
                jsonObject.put("text","@"+dto.getSenderStaffId()+jsonObject.getString("text"));
                groupPushServiceOnWebhookMarkdown(jsonObject, dto.getSenderStaffId(), dto.getSessionWebhook());
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 获取产品信息 推送卡片信息
     *
     * @param uids
     */
    public void productCardPush(List<String> uids, String reqmsg,RobotResDTO dto) {
        //获取产品信息 reqmsg
        String productName = getProducts(reqmsg);
        if (StringUtils.isBlank(productName)) {
            productName = ">* 找不到关键字产品,请重试!!";
        }
        log.info("产品查询显示列表---->{}", productName);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("title", "搜索结果返回");
        jsonObject.put("text", "为您找到如下结果  \n  ***  \n  "+productName);
        try {
            if(dto.getConversationType().equals("1")){
                //单聊
                Client client = dingBasicService.createClient();
                String token = dingBasicService.getToken("dingrobottag");
                BatchSendOTOHeaders headers = new BatchSendOTOHeaders();
                headers.xAcsDingtalkAccessToken = token;
                BatchSendOTORequest request = new BatchSendOTORequest().setRobotCode(ROBOTID).setUserIds(uids).setMsgKey("sampleMarkdown").setMsgParam(JSONObject.toJSONString(jsonObject));

                BatchSendOTOResponse response = client.batchSendOTOWithOptions(request, headers, new RuntimeOptions());
                log.info("回答文本服务---->", JSONObject.toJSONString(response));
            }else{
                //群聊
                jsonObject.put("text","@"+dto.getSenderStaffId() + jsonObject.getString("text"));
                groupPushServiceOnWebhookMarkdown(jsonObject, dto.getSenderStaffId(), dto.getSessionWebhook());
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //接口 获取 中台中的产品价格
    private String getProducts(String reqmsg) {
        String url = String.format("%s%s", CPURL, "api/presale/customiz/backEnd/productPrices/list?pageSize=15&pageNum=0&productName=" + reqmsg + "&productCode&brand");
        try {
            String ret = httpAPIServiceForDing.doPost(url);

            if (StringUtils.isBlank(ret)) {
                return null;
            }
            JSONObject jsonObject = JSONObject.parseObject(ret);
            int sum = 0;
            log.info("请求返回---->{}", ret);
            JSONObject jsonObject1 = jsonObject.getJSONObject("data");
            sum = jsonObject1.getInteger("totalElements");
            if (sum == 0) {
                return null;
            }
            JSONArray jsonArray = jsonObject1.getJSONArray("list");
            //整理明细
            StringBuilder sb = new StringBuilder();
            for (Object j : jsonArray) {
                JSONObject _j = (JSONObject) j;
                sb.append("* <font color=\"#e91e63\">产品名称:</font>" + _j.getString("productName") + " 编码:" + _j.getString("productCode") + " 规格:" +_j.getString("specs") +" ");
                sb.append("<font color=\"#2196f3\">价格:</font>" + _j.getString("standardPrice") + "元  \n  ");
            }
            if (sum > 16) {
                sb.append("<font color=\"#e91e63\">注意!!!搜索结果多余15个,只显示第一页</font>  \n  ");
            }
            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 修改指定 用户的每刻 部门
     * @param uids
     * @param reqmsg
     * @param dto
     * @return
     */
    public void changeMaycurUserDept(List<String> uids, String reqmsg,RobotResDTO dto){
        String userId = uids.get(0);
        //地址写死
        String url = String.format("%s%s", MAYCURURL, "/maycur/sync/aiChangeUserDept?uid="+userId+"_"+reqmsg);
        log.info("请求url---->>>>>{}", url);
        try {
            String ret = httpAPIServiceForDing.doPost(url);
            log.info("------->>>修改指定 用户的每刻 部门 结果:{}", ret);
            if (StringUtils.isNotBlank(ret)) {
                JSONObject req = new JSONObject();
                req.put("title", "更新回复");
                req.put("text", ret);
                if (dto.getConversationType().equals("1")) {
                    //单聊
                    Client client = dingBasicService.createClient();
                    String token = dingBasicService.getToken("dingrobottag");
                    BatchSendOTOHeaders headers = new BatchSendOTOHeaders();
                    headers.xAcsDingtalkAccessToken = token;
                    BatchSendOTORequest request = new BatchSendOTORequest().setRobotCode(ROBOTID).setUserIds(uids).setMsgKey("sampleMarkdown").setMsgParam(JSONObject.toJSONString(req));
                    BatchSendOTOResponse response = client.batchSendOTOWithOptions(request, headers, new RuntimeOptions());
                    log.info("回答文本服务---->成功");
                }
            }
        } catch (Exception e) {
            log.info("------->>>修改指定 用户的每刻 部门 异常");
        }

    }

    /**
     * 回答模版推送服务
     * 不用
     */
    public void answerCardMuti(List<String> uids, JSONObject entity) {
        try {
            Client client = dingBasicService.createClient();
            String token = dingBasicService.getToken("dingrobottag");
            BatchSendOTOHeaders headers = new BatchSendOTOHeaders();
            headers.xAcsDingtalkAccessToken = token;
            BatchSendOTORequest request = new BatchSendOTORequest().setRobotCode(ROBOTID).setUserIds(uids).setMsgKey("sampleActionCard3").setMsgParam(JSONObject.toJSONString(entity));
            BatchSendOTOResponse response = client.batchSendOTOWithOptions(request, headers, new RuntimeOptions());
            log.info("回答文本服务---->成功");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 回答文本服务 标准回答
     * 测试用
     */
    public void answerMsg(List<String> uids, JSONObject msg) {
        try {
            JSONObject retJson = new JSONObject();
            retJson.put("content", "无法回答该问题哦!请重新提问");
            Client client = dingBasicService.createClient();
            String token = dingBasicService.getToken("dingrobottag");
            BatchSendOTOHeaders headers = new BatchSendOTOHeaders();
            headers.xAcsDingtalkAccessToken = token;
            BatchSendOTORequest request = new BatchSendOTORequest().setRobotCode(ROBOTID).setUserIds(uids).setMsgKey("sampleMarkdown").setMsgParam(JSONObject.toJSONString(msg));
            BatchSendOTOResponse response = client.batchSendOTOWithOptions(request, headers, new RuntimeOptions());
            log.info("回答文本服务---->", JSONObject.toJSONString(response));
        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                System.out.println(err.code);
                System.out.println(err.message);
            }else{
                System.out.println(err.code);
                System.out.println(err.message);
            }
        }

    }

    /**
     * 异常处理通用回答
     *
     * @param uids
     */
    public void answerErrorMsg(List<String> uids, RobotResDTO dto) {
        try {
            JSONObject retJson = new JSONObject();
            retJson.put("title", "搜索结果返回");
            retJson.put("text", " 答复  \n  ***  \n  > * 你好像没有提问哦.请重新提问吧(*^▽^*) ");
            if(dto.getConversationType().equals("1")){
                //单聊
                Client client = dingBasicService.createClient();
                String token = dingBasicService.getToken("dingrobottag");
                BatchSendOTOHeaders headers = new BatchSendOTOHeaders();
                headers.xAcsDingtalkAccessToken = token;
                BatchSendOTORequest request = new BatchSendOTORequest().setRobotCode(ROBOTID).setUserIds(uids).setMsgKey("sampleMarkdown").setMsgParam(JSONObject.toJSONString(retJson));
                BatchSendOTOResponse response = client.batchSendOTOWithOptions(request, headers, new RuntimeOptions());
                log.info("回答文本服务成功---->");
            }else{
                //群聊
                retJson.put("text","@"+dto.getSenderStaffId()+retJson.getString("text"));
                groupPushServiceOnWebhookMarkdown(retJson, dto.getSenderStaffId(), dto.getSessionWebhook());
            }

        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            System.out.println("error----->" + _err);
        }

    }

    /**
     * 标准回答
     *
     * @param uids
     * @param msg
     */
    public void productDefaultPush(List<String> uids, String msg,RobotResDTO dto) {
        //获取产品信息 reqmsg
        if (StringUtils.isBlank(msg)) {
//            msg = "我可以回答:  \n  * 产品标准价格(格式:产品价格+\"名称关键字\")  \n  * 知识库内容(格式:知识库+\"要问的内容\")  \n * 修改部门(格式:修改部门+临床学术部(或者内蒙大区等)||华北省区 或 山西大区)";
            msg = "我可以回答:  \n  * 产品标准价格(格式:产品价格+\"名称关键字\")  \n  * 知识库内容(格式:知识库+\"要问的内容\")  \n * 修改部门(格式:修改部门+(可修改的部门)||(支持修改的部门:山西大区、华北省区、豫鄂省区、福建省区、临床学术部))";
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("title", "机器人问答格式!");
        jsonObject.put("text", msg);
        try {
            if(dto.getConversationType().equals("1")){
                //单聊
                Client client = dingBasicService.createClient();
                String token = dingBasicService.getToken("dingrobottag");
                BatchSendOTOHeaders headers = new BatchSendOTOHeaders();
                headers.xAcsDingtalkAccessToken = token;
                BatchSendOTORequest request = new BatchSendOTORequest().setRobotCode(ROBOTID).setUserIds(uids).setMsgKey("sampleMarkdown").setMsgParam(JSONObject.toJSONString(jsonObject));

                BatchSendOTOResponse response = client.batchSendOTOWithOptions(request, headers, new RuntimeOptions());
                log.info("回答文本服务(默认文本)---->", JSONObject.toJSONString(response));
            }else{
                //群聊
                jsonObject.put("text","@"+dto.getSenderStaffId()+jsonObject.getString("text"));
                groupPushServiceOnWebhookMarkdown(jsonObject, dto.getSenderStaffId(), dto.getSessionWebhook());
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 群内回复 不AT人员
     * 不计划用
     *
     * @param openConversationId
     * @param msgParam
     */
    private void groupPushServiceMarkdown(String openConversationId, Object msgParam) {
        Client client = dingBasicService.createClient();
        String token = dingBasicService.getToken("dingrobottag");
        OrgGroupSendHeaders orgGroupQueryHeaders = new OrgGroupSendHeaders();
        orgGroupQueryHeaders.setXAcsDingtalkAccessToken(token);
        OrgGroupSendRequest request = new OrgGroupSendRequest().setRobotCode(ROBOTID).setOpenConversationId(openConversationId).setMsgKey("sampleMarkdown").setMsgParam(JSONObject.toJSONString(msgParam));
        try {
            OrgGroupSendResponse response = client.orgGroupSendWithOptions(request, orgGroupQueryHeaders, new RuntimeOptions());
            log.info("回答文本服务--->", JSONObject.toJSONString(response.body));
        } catch (Exception e) {
            e.printStackTrace();
            log.info("异常信息---->{}", e.toString());
        }


    }

    //群答复 使用的方法 markdown
    private void groupPushServiceOnWebhookMarkdown(JSONObject rspJson,String uid,String webhook) {
        DingTalkClient client = new DefaultDingTalkClient(webhook);
        OapiRobotSendRequest request = new OapiRobotSendRequest();
        request.setMsgtype("markdown");
        OapiRobotSendRequest.Markdown text = new OapiRobotSendRequest.Markdown();
        text.setTitle(rspJson.getString("title"));
        text.setText(rspJson.getString("text"));
        request.setMarkdown(text);
        OapiRobotSendRequest.At at = new OapiRobotSendRequest.At();
        at.setAtUserIds(Arrays.asList(uid));
        at.setIsAtAll(false);
        request.setAt(at);
        OapiRobotSendResponse response = null;
        try {
            response = client.execute(request);
            log.info("回答文本服务--->{}", JSONObject.toJSONString(response.getBody()));
        } catch (ApiException e) {
            e.printStackTrace();
        }
    }


    /**
     * content 编码
     *
     * @param s
     * @return
     */
    private String encodeS(String s) {
        try {
            return URLEncoder.encode(s, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
    }

}
